﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;
using BesAsm.Stormwater.HspfCore;
using BesAsm.Stormwater.HspfResults;

namespace BesAsm.Stormwater.HspfResults
{
  public class Wh2Reader
  {
    private List<Catchment> _catchments;
    private List<int> _segmentNumbers;
    private string _wh2File;
    public bool IsRead { get; private set; }

    public Wh2Reader(string wh2File)
    {
      _wh2File = wh2File;
      IsRead = false;
    }

    public void Read()
    {
      _catchments = new List<Catchment>();
      _segmentNumbers = new List<int>();

      StreamReader reader = new StreamReader(_wh2File);
      List<string> wh2CatchmentBlock = new List<string>();
      bool inElementBlock = false;

      string line = reader.ReadLine();

      while (!reader.EndOfStream)
      {
        if (line.StartsWith("[name, "))
        {
          inElementBlock = true;
        }
        else if (inElementBlock)
        {
          wh2CatchmentBlock.Add(line);
        }

        if (line.StartsWith("[END POND"))
        {
          Catchment catchment = ReadCatchment(wh2CatchmentBlock);

          if (catchment != null)
          _catchments.Add(catchment);

          inElementBlock = false;
          wh2CatchmentBlock.Clear();
        }
        else if (line.StartsWith("{end"))
        {
          inElementBlock = false;
          wh2CatchmentBlock.Clear();
        }

        line = reader.ReadLine();
      }
      IsRead = true;
      return;
    }

    public List<Catchment> Catchments
    {
      get
      {
        if (IsRead)
          return _catchments;
        else
          throw new Exception("Wh2 Data has not been read");
      }

    }

    private Catchment ReadCatchment(List<string> block)
    {
      if (block.Count == 0) return null;

      string name = block[0];
      int implandCount, perlandCount = 0;

      Catchment catchment = new Catchment(name);

      for (int i = 0; i < block.Count; i++)
      {
        string s = block[i];

        if (s.StartsWith("[landiusecount, "))
          implandCount = int.Parse(block[i + 1]);
        else if (s.StartsWith("[landuse count, "))
          perlandCount = int.Parse(block[i + 1]);
        else if (s.StartsWith("IMPLND"))
        {
          int segmentNum = int.Parse(block[i + 5]);
          double acres = double.Parse(block[i - 2]);

          catchment.AddSegment(SegmentType.Impland, segmentNum, acres);
          if (!_segmentNumbers.Contains(segmentNum))
            _segmentNumbers.Add(segmentNum);
        }
        else if (s.StartsWith("PERLND"))
        {
          int segmentNum = int.Parse(block[i + 5]);
          double acres = double.Parse(block[i - 2]);

          catchment.AddSegment(SegmentType.Perland, segmentNum, acres);
          if (!_segmentNumbers.Contains(segmentNum))
            _segmentNumbers.Add(segmentNum);
        }
      }

      return catchment;
    }

    public DataTable GetDataTable()
    {
      DataTable dt = new DataTable();

      dt.Columns.Add("Name", typeof(string));
      dt.Columns.Add("TotalArea", typeof(double));

      foreach (int i in _segmentNumbers.OrderBy(p => p))
      {
        dt.Columns.Add("Seg" + i + "Area", typeof(double));
      }

      foreach (Catchment catchment in _catchments)
      {
        DataRow row = dt.NewRow();
        row[0] = catchment.Name;
        row[1] = catchment.Segments.Sum(p => p.Area);
        int i = 2;
        foreach (ILandSegment ls in catchment.Segments.OrderBy(p => p.SegmentNumber))
        {
          int colIndex = _segmentNumbers.IndexOf(ls.SegmentNumber) + 2;
          row[colIndex] = ls.Area;
        }
        dt.Rows.Add(row);
      }

      return dt;
    }

  }
}
